﻿using CozeDomain.IRepositories;
using CozeDomain.Entities;
using CozeDto.SysDicTypeDtos;
using CozeDto.SysDicDtos;
using D.UtilFreesqlOrm;

namespace CozeDomain.Repositories
{
    /// <summary>
    /// 
    /// </summary>
    public class SysDicEntityRepository : BaseRepository<SysDicEntity>, ISysDicEntityRepository
    {
        public SysDicEntityRepository(IFreeSql db) : base(db)
        {
        }

        #region 获取分页列表

        /// <summary>
        /// 
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<Tuple<long,List<RepQuerySysDicTreeTable>>> GetPagesAsync(ReqQuerySysDicPage query)
        {
            FreeSql.ISelect<SysDicEntity> getSelect() => _db.Select<SysDicEntity>()
                                                .WhereIf(!string.IsNullOrEmpty(query.Name), m => m.Name.Contains(query.Name))
                                                .WhereIf(query.Status != null, m => m.Status == query.Status)
                                                .WhereIf(!string.IsNullOrEmpty(query.DicTypeUniqueCode), m => m.DicTypeUniqueCode == query.DicTypeUniqueCode)
                                                //.WhereIf(!string.IsNullOrEmpty(query.ParentId), m => m.ParentId == query.ParentId)
                                                .OrderByDescending(m => m.CreateTime);

        

            var childList = getSelect().Where(m => !string.IsNullOrEmpty(m.ParentId)).ToList();
            var parentQuery = getSelect().Where(m => string.IsNullOrEmpty(m.ParentId));
            
            var parentList = await parentQuery.Count(out var totalCount)
                                                             .Page(query.PageNo, query.PageSize)
                                                             .ToListAsync();


            var treeList = new List<RepQuerySysDicTreeTable>();
            foreach (var m in parentList)
            {
                treeList.Add(new RepQuerySysDicTreeTable()
                {
                    Id = m.Id,
                    Name = m.Name,
                    Val = m.Val,
                    ParentId = m.ParentId,
                    Description = m.Description,
                    CreateTime = m.CreateTime,
                    CreateUser = m.CreateUser,
                    Status = m.Status,
                    Key = m.Id,
                    Children = GetTableChild(childList, m.Id)
                });
            }

            return new Tuple<long, List<RepQuerySysDicTreeTable>>(totalCount, treeList);
             
        }
        private List<RepQuerySysDicTreeTable> GetTableChild(List<SysDicEntity> all, string id)
        {
            
            var childer = all.Where(m => m.ParentId == id);
            if (childer.Any())
            {
                return childer.Select(m => new RepQuerySysDicTreeTable()
                {
                    Id = m.Id,
                    Name = m.Name,
                    Val = m.Val,
                    ParentId = m.ParentId,
                    Description = m.Description,
                    CreateTime = m.CreateTime,
                    CreateUser = m.CreateUser,
                    Status = m.Status,
                    Key = m.Id,
                    Children = GetTableChild(all, m.Id)
                }).ToList();
            }
            return null;
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dicTypeUniqueCode"></param>
        /// <returns></returns>
        public async Task<List<RepSelect>> QueryDicSelect(string dicTypeUniqueCode)
        {
            return await _db.Queryable<SysDicEntity>() 
                              .Where(m => m.DicTypeUniqueCode == dicTypeUniqueCode) 
                              .ToListAsync(m => new RepSelect()
                              {
                                  Id = m.Id,
                                  Name = m.Name,
                                  Value = m.Val
                              });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dicTypeUniqueCode"></param>
        /// <returns></returns>
        public async Task<List<RepTreeSelect>> QueryDicTreeSelect(string dicTypeUniqueCode)
        {
            return await _db.Queryable<SysDicEntity>()
                            .Where(m => m.DicTypeUniqueCode == dicTypeUniqueCode) 
                            .ToListAsync(m => new RepTreeSelect()
                            {
                                Id = m.Id,
                                PId = m.ParentId ?? "",
                                Title = m.Name,
                                Value = m.Val,
                                IsLeaf = !string.IsNullOrEmpty(m.ParentId)
                            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dicTypeUniqueCode"></param>
        /// <returns></returns>
        public async Task<List<RepTreeList>> QueryDicTreeSelect2(string dicTypeUniqueCode)
        {
            var allList = await _db.Select<SysDicEntity>() 
                                     .Where(m => m.DicTypeUniqueCode == dicTypeUniqueCode)
                                     .ToListAsync();

            var list = new List<RepTreeList>();
            foreach (var m in allList.Where(m => string.IsNullOrEmpty(m.ParentId)))
            {
                list.Add(new RepTreeList()
                {
                    Value = m.Id,
                    Label = m.Name,
                    Children = GetTreeChild(allList, m.Id)
                });
            }
            return list;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="all"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        private List<RepTreeList>? GetTreeChild(List<SysDicEntity> all, string id)
        {
            var childer = all.Where(m => m.ParentId == id);
            if (childer.Any())
            {
                return childer.Select(m => new RepTreeList()
                {
                    Value = m.Id,
                    Label = m.Name,
                    Children = GetTreeChild(all, m.Id)
                }).ToList();
            }
            return null;
        }
    }
}
